import 'package:get/get.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:convert';
import 'dart:async';
import '../../device_detail/widgets/record_data_manager.dart';
import '../../../data/services/playback_service.dart';
import '../../../data/services/user_service.dart';
import '../../../data/services/download_database_service.dart';
import '../../download/controllers/download_controller.dart';
import '../../../data/models/download_record.dart';

class VideoListController extends GetxController {
  // 存储类型：cloud 或 local
  final RxString storageType = 'cloud'.obs;

  // 时间选择
  final RxString startTime = ''.obs;
  final RxString endTime = ''.obs;
  final RxString selectedDate =
      DateTime.now().toString().substring(0, 10).obs; // 默认今天

  // 加载状态
  final RxBool isLoading = false.obs;

  // 视频列表
  final RxList<Map<String, dynamic>> videoList = <Map<String, dynamic>>[].obs;

  // 录像数据管理器
  final RecordDataManager _recordDataManager = RecordDataManager();

  // 服务实例
  final PlaybackService _playbackService = Get.find<PlaybackService>();

  // 设备信息（从路由参数获取）
  String _deviceId = '';
  String _channelId = '';
  String _deviceName = '';
  String _channelName = '';

  @override
  void onInit() {
    super.onInit();
    _initializeFromArguments();
    loadVideoList();
  }

  @override
  void onReady() {
    super.onReady();
  }

  @override
  void onClose() {
    super.onClose();
  }

  /// 从路由参数初始化设备信息
  void _initializeFromArguments() {
    final arguments = Get.arguments as Map<String, dynamic>?;
    if (arguments != null) {
      _deviceId = arguments['deviceId']?.toString() ?? '';
      _channelId = arguments['channelId']?.toString() ?? '';
      _deviceName = arguments['deviceName']?.toString() ?? '未知设备';
      _channelName = arguments['channelName']?.toString() ?? '未知通道';
      print(
        '视频列表页参数：deviceId=$_deviceId, channelId=$_channelId, deviceName=$_deviceName, channelName=$_channelName',
      );
    } else {
      print('视频列表页未收到参数');
      BotToast.showText(text: '设备信息获取失败');
    }
  }

  /// 切换存储类型
  void switchStorageType(String type) {
    storageType.value = type;
    loadVideoList();
  }

  /// 设置开始时间
  void setStartTime(DateTime dateTime) {
    startTime.value =
        '${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
  }

  /// 设置结束时间
  void setEndTime(DateTime dateTime) {
    endTime.value =
        '${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
  }

  /// 清空开始时间
  void clearStartTime() {
    startTime.value = '';
  }

  /// 清空结束时间
  void clearEndTime() {
    endTime.value = '';
  }

  /// 清空所有时间
  void clearAllTimes() {
    startTime.value = '';
    endTime.value = '';
  }

  /// 设置选中日期
  void setSelectedDate(DateTime date) {
    selectedDate.value =
        '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
    loadVideoList();
  }

  /// 加载视频列表
  Future<void> loadVideoList() async {
    if (_deviceId.isEmpty) {
      print('设备ID为空，无法加载视频列表');
      return;
    }

    isLoading.value = true;
    videoList.clear();

    try {
      print('🎬 开始加载视频列表');
      print('🎬 存储类型: ${storageType.value}');
      print('🎬 设备ID: $_deviceId, 通道ID: $_channelId');

      // 根据是否有自定义时间范围决定查询方式
      if (startTime.value.isNotEmpty && endTime.value.isNotEmpty) {
        // 自定义时间范围查询
        await _loadVideoListByTimeRange();
      } else {
        // 按日期查询
        await _loadVideoListByDate();
      }
    } catch (e) {
      print('❌ 加载视频列表失败: $e');
      BotToast.showText(text: '加载视频数据失败，请稍后重试');
    } finally {
      isLoading.value = false;
    }
  }

  /// 按日期加载视频列表
  Future<void> _loadVideoListByDate() async {
    try {
      final date = DateTime.parse(selectedDate.value);
      print('📅 按日期加载视频列表: ${selectedDate.value}');

      // 使用录像数据管理器加载数据
      final segments = await _recordDataManager.loadRecordData(
        deviceId: _deviceId,
        channelId: _channelId,
        date: date,
        sourceType: storageType.value,
      );

      // 转换为视频列表格式
      final videos =
          segments.map((segment) => _convertSegmentToVideo(segment)).toList();
      videoList.value = videos;

      print('✅ 按日期加载完成，共 ${videos.length} 条记录');
    } catch (e) {
      print('❌ 按日期加载视频列表失败: $e');
      rethrow;
    }
  }

  /// 按时间范围加载视频列表
  Future<void> _loadVideoListByTimeRange() async {
    try {
      print('⏰ 按时间范围加载视频列表');
      print('⏰ 开始时间: ${startTime.value}');
      print('⏰ 结束时间: ${endTime.value}');

      // 解析时间范围
      final startDateTime = DateTime.parse(startTime.value);
      final endDateTime = DateTime.parse(endTime.value);

      // 按天遍历时间范围
      final videos = <Map<String, dynamic>>[];
      DateTime currentDate = DateTime(
        startDateTime.year,
        startDateTime.month,
        startDateTime.day,
      );
      final endDate = DateTime(
        endDateTime.year,
        endDateTime.month,
        endDateTime.day,
      );

      while (!currentDate.isAfter(endDate)) {
        print('📅 加载日期: ${currentDate.toString().substring(0, 10)}');

        // 加载当天的录像数据
        final segments = await _recordDataManager.loadRecordData(
          deviceId: _deviceId,
          channelId: _channelId,
          date: currentDate,
          sourceType: storageType.value,
        );

        // 过滤时间范围内的片段
        for (final segment in segments) {
          if (segment.startTime.isAfter(startDateTime) &&
              segment.startTime.isBefore(endDateTime)) {
            videos.add(_convertSegmentToVideo(segment));
          }
        }

        currentDate = currentDate.add(Duration(days: 1));
      }

      videoList.value = videos;
      print('✅ 按时间范围加载完成，共 ${videos.length} 条记录');
    } catch (e) {
      print('❌ 按时间范围加载视频列表失败: $e');
      rethrow;
    }
  }

  /// 将录像片段转换为视频列表格式
  Map<String, dynamic> _convertSegmentToVideo(RecordSegment segment) {
    return {
      'id': segment.id,
      'time': segment.time,
      'duration': segment.duration,
      'type': segment.type,
      'hour': segment.hour,
      'picUrl': segment.picUrl,
      'playUrl': segment.playUrl,
      'source': segment.source,
      'startTime': segment.startTime,
      'endTime': segment.endTime,
    };
  }

  /// 处理录像下载
  Future<void> handleRecordDownload(Map<String, dynamic> record) async {
    try {
      print('🎬 开始处理录像下载');

      // 获取录像信息
      final startTime = record['startTime'] as DateTime?;
      final endTime = record['endTime'] as DateTime?;
      final duration = record['duration'] as String? ?? '';
      final source = record['source'] as String? ?? '';
      final picUrl = record['picUrl'] as String? ?? '';

      if (startTime == null || endTime == null) {
        BotToast.showText(text: '录像时间信息不完整');
        return;
      }

      // 格式化时间为API需要的格式 (YYYYMMDDHHmmss)
      final startTimeStr = _formatDateTimeForCloudAPI(startTime);
      final endTimeStr = _formatDateTimeForCloudAPI(endTime);

      // 根据source判断storeType: 'local' -> 1(设备存储), 'cloud' -> 2(中心存储)
      final storeType = source == 'local' ? 1 : 2;

      print('📊 录像下载信息:');
      print('  设备ID: $_deviceId');
      print('  通道ID: $_channelId');
      print('  存储类型: $storeType ($source)');
      print('  开始时间: $startTimeStr');
      print('  结束时间: $endTimeStr');
      print('  时长: $duration');

      // 先检查存储权限
      await _checkStoragePermission();

      // 调用录像下载接口
      BotToast.showLoading();
      final response = await _playbackService.downloadRecord(
        deviceId: _deviceId,
        channelId: _channelId,
        storeType: storeType,
        startTime: startTimeStr,
        endTime: endTimeStr,
      );
      BotToast.closeAllLoading();

      print('📡 录像下载接口响应: $response');

      if (response['code'] == 0 && response['success'] == true) {
        final data = response['data'] as String?;

        if (data == null || data.isEmpty) {
          BotToast.showText(text: '该时间段无录像数据');
          return;
        }

        print('🔗 获取到下载地址: $data');

        // 判断是直接下载地址还是WebSocket地址
        if (data.startsWith('ws://') || data.startsWith('wss://')) {
          // WebSocket地址，需要建立连接获取下载链接
          // WebSocket需要ISO格式时间（YYYY-MM-DDTHH:mm:00），秒数固定为00
          final startTimeISO = _convertTimeFormatToISOForWebSocket(
            startTimeStr,
          );
          final endTimeISO = _convertTimeFormatToISOForWebSocket(endTimeStr);

          print('🔌 检测到WebSocket地址，建立连接...');
          print('📅 WebSocket时间格式:');
          print('  开始时间: $startTimeISO');
          print('  结束时间: $endTimeISO');

          await _handleWebSocketDownload(
            wsUrl: data,
            startTime: startTimeISO,
            endTime: endTimeISO,
            duration: duration,
            picUrl: picUrl,
          );
        } else {
          // 直接下载地址
          print('🔗 检测到直接下载地址，开始下载...');
          await _startDirectDownload(
            downloadUrl: data,
            startTime: startTimeStr,
            endTime: endTimeStr,
            duration: duration,
            picUrl: picUrl,
          );
        }
      } else {
        final errorMsg = response['msg'] as String? ?? '录像下载失败';
        print('❌ 录像下载失败: $errorMsg');
        BotToast.showText(text: errorMsg);
      }
    } catch (e) {
      print('❌ 处理录像下载失败: $e');
      BotToast.showText(text: '下载失败，请稍后重试');
      BotToast.closeAllLoading();
    }
  }

  /// 处理本地录像下载
  Future<void> _handleLocalVideoDownload({
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      print('🎯 开始本地录像下载流程...');

      // 先检查存储权限
      await _checkStoragePermission();

      // 🔄 参考 device_detail_controller 的方式，调用 startPlayback 获取播放地址
      BotToast.showLoading();

      // 转换时间格式为 API 需要的格式
      final startTimeForAPI = _convertTimeFormatToAPI(startTime);
      final endTimeForAPI = _convertTimeFormatToAPI(endTime);

      print('📡 调用 startPlayback 获取本地录像播放地址');
      print('  开始时间: $startTimeForAPI');
      print('  结束时间: $endTimeForAPI');

      final response = await _playbackService.startPlayback(
        serial: _deviceId,
        starttime: startTimeForAPI,
        endtime: endTimeForAPI,
      );
      BotToast.closeAllLoading();

      print('📡 startPlayback 接口响应: $response');

      if (response != null && response['code'] == 0) {
        final data = response['data'] as Map<String, dynamic>?;
        final flvUrl = data?['FLV'] as String?;

        if (flvUrl != null && flvUrl.isNotEmpty) {
          print('🔗 获取到本地录像FLV流媒体地址: $flvUrl');

          // FLV 是流媒体，使用流媒体下载方式（类似 HLS）
          await _startLocalStreamDownload(
            streamUrl: flvUrl,
            startTime: startTime,
            endTime: endTime,
            duration: duration,
            picUrl: picUrl,
          );
        } else {
          BotToast.showText(text: '该时间段无录像数据');
        }
      } else {
        throw Exception(response?['msg'] ?? '设备繁忙，请稍后重试');
      }
    } catch (e) {
      print('❌ 本地录像下载失败: $e');
      BotToast.showText(text: '下载失败，请稍后重试');
      BotToast.closeAllLoading();
    }
  }

  /// 开始本地流媒体下载（FLV/HLS）- 集成到下载管理系统
  Future<void> _startLocalStreamDownload({
    required String streamUrl,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      print('🎯 开始本地流媒体下载...');
      print('📡 流地址: $streamUrl');

      // 转换时间格式（从YYYYMMDDHHmmss到ISO格式）
      final startTimeISO = _convertTimeFormatToISO(startTime);
      final endTimeISO = _convertTimeFormatToISO(endTime);

      print('🎬 转换后的ISO时间格式:');
      print('  开始时间: $startTimeISO');
      print('  结束时间: $endTimeISO');

      // 检查并获取下载控制器
      if (!Get.isRegistered<DownloadController>()) {
        print('❌ DownloadController 未注册，尝试重新注册');
        Get.put(DownloadController(), permanent: true);
      }

      final downloadController = Get.find<DownloadController>();
      print('✅ 成功获取下载控制器');

      // 检查是否已存在相同的下载记录
      final existingRecords =
          downloadController.downloadRecords
              .where(
                (record) =>
                    record.videoUrl == streamUrl &&
                    record.startTime == startTimeISO &&
                    record.endTime == endTimeISO,
              )
              .toList();

      if (existingRecords.isNotEmpty) {
        final existingRecord = existingRecords.first;
        if (existingRecord.status == DownloadStatus.waiting ||
            existingRecord.status == DownloadStatus.downloading) {
          BotToast.showText(text: '该视频正在下载中，请稍候');
          return;
        } else if (existingRecord.status == DownloadStatus.completed) {
          BotToast.showText(text: '下载完成，请前往我的下载进行查看');
          return;
        }
      }

      // 使用 DownloadController 的 startDownload 方法
      // 这会自动创建下载记录、保存到数据库、显示在下载页面
      await downloadController.startDownload(
        hlsUrl: streamUrl,
        deviceName: _deviceName,
        deviceId: _deviceId,
        channelId: _channelId,
        channelName: _channelName,
        startTime: startTimeISO,
        endTime: endTimeISO,
        duration: duration,
        picUrl: picUrl.isNotEmpty ? picUrl : '',
      );

      print('✅ 本地流媒体下载已启动');
      BotToast.showText(text: '录像下载已开始，请在下载页面查看进度');

      // 强制更新UI
      update();
    } catch (e) {
      print('❌ 本地流媒体下载失败: $e');
      BotToast.showText(text: '下载服务未初始化，请稍后重试');
    }
  }

  /// 处理云端录像下载
  Future<void> _handleCloudVideoDownload({
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      print('🎯 开始云端录像下载流程...');

      // 先检查存储权限
      await _checkStoragePermission();

      // 调用云端录像下载接口

      BotToast.showLoading();
      final response = await _playbackService.cloudVideo(
        serial: _deviceId,
        code: _channelId,
        operate: 'download',
        starttime: startTime,
        endtime: endTime,
      );
      BotToast.closeAllLoading();

      print('📡 云端录像下载接口响应: $response');

      if (response['code'] == 0 && response['success'] == true) {
        final data = response['data'];

        // 解析返回的Map格式数据
        String? downloadUrl;
        String? coverUrl;

        if (data is Map<String, dynamic>) {
          // data 是对象，包含 VideoUrl 和 CoverUrl
          // 注意：字段名可能有前导空格（API文档中的样例有空格）
          downloadUrl =
              data['VideoUrl'] as String? ??
              data[' VideoUrl'] as String?; // 兼容有空格的情况
          coverUrl =
              data['CoverUrl'] as String? ??
              data[' CoverUrl'] as String?; // 兼容有空格的情况

          print('📦 返回数据:');
          print('  VideoUrl: $downloadUrl');
          print('  CoverUrl: $coverUrl');
        } else {
          print('⚠️ 返回数据格式异常: ${data.runtimeType}');
        }

        if (downloadUrl != null && downloadUrl.isNotEmpty) {
          print('🔗 获取到下载链接: $downloadUrl');
          print('🖼️ 封面图链接: ${coverUrl ?? "无"}');

          // 集成现有的下载流程，使用返回的封面图（如果有的话）
          await _startCloudDownload(
            downloadUrl: downloadUrl,
            startTime: startTime,
            endTime: endTime,
            duration: duration,
            picUrl: coverUrl ?? picUrl, // 优先使用返回的封面图
          );
        } else {
          BotToast.showText(text: '该时间段无录像数据');
        }
      } else {
        // 错误处理 - 提供更友好的提示
        final errorMsg = response['msg'] as String? ?? '云端录像下载失败';

        // 判断是否是录像文件未找到的错误
        if (errorMsg.contains('not found') ||
            errorMsg.contains('ts file') ||
            errorMsg.contains('404')) {
          print('📭 该时间段无录像文件');
          BotToast.showText(text: '该时间段无录像数据');
        } else {
          print('❌ 云端录像下载失败: $errorMsg');
          BotToast.showText(text: '录像获取失败，请稍后重试');
        }
        return; // 不抛出异常，避免重复显示错误提示
      }
    } catch (e) {
      print('❌ 云端录像下载失败: $e');
      BotToast.showText(text: '下载失败，请稍后重试');
      BotToast.closeAllLoading();
    }
  }

  /// 开始云端下载
  Future<void> _startCloudDownload({
    required String downloadUrl,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      print('🎯 开始云端下载...');

      // 检查并获取下载控制器
      if (!Get.isRegistered<DownloadController>()) {
        print('❌ DownloadController 未注册，尝试重新注册');
        Get.put(DownloadController(), permanent: true);
      }

      final downloadController = Get.find<DownloadController>();
      print('✅ 成功获取下载控制器');

      // 检查是否已存在相同的下载记录
      final existingRecords =
          downloadController.downloadRecords
              .where(
                (record) =>
                    record.videoUrl == downloadUrl &&
                    record.startTime == startTime &&
                    record.endTime == endTime,
              )
              .toList();

      if (existingRecords.isNotEmpty) {
        final existingRecord = existingRecords.first;
        if (existingRecord.status == DownloadStatus.waiting ||
            existingRecord.status == DownloadStatus.downloading) {
          BotToast.showText(text: '该视频正在下载中，请稍候');
          return;
        } else if (existingRecord.status == DownloadStatus.completed) {
          BotToast.showText(text: '下载完成，请前往我的下载进行查看');
          return;
        } else if (existingRecord.status == DownloadStatus.failed ||
            existingRecord.status == DownloadStatus.paused) {
          if (existingRecord.status == DownloadStatus.failed) {
            BotToast.showText(text: '检测到失败的下载，正在重新开始...');
          } else {
            BotToast.showText(text: '检测到暂停的下载，正在重新开始...');
          }
        }
      }

      // 转换时间格式（从YYYYMMDDHHmmss到ISO格式）
      final startTimeISO = _convertTimeFormatToISO(startTime);
      final endTimeISO = _convertTimeFormatToISO(endTime);

      print('🎬 转换后的ISO时间格式:');
      print('  开始时间: $startTimeISO');
      print('  结束时间: $endTimeISO');

      // 开始下载 - 使用MP4下载方法
      print('🚀 调用startMp4Download方法...');
      await downloadController.startMp4Download(
        downloadUrl: downloadUrl,
        deviceName: _deviceName,
        deviceId: _deviceId,
        channelId: _channelId,
        channelName: _channelName,
        startTime: startTimeISO,
        endTime: endTimeISO,
        duration: duration,
        picUrl: picUrl.isNotEmpty ? picUrl : '', // 使用空字符串，让UI显示默认图片
      );

      print('✅ 云端录像下载已启动');
      BotToast.showText(text: '录像下载已开始，请在下载页面查看进度');

      // 强制更新UI
      update();
    } catch (e) {
      print('❌ 云端录像下载失败: $e');
      BotToast.showText(text: '下载服务未初始化，请稍后重试');
    }
  }

  /// 处理WebSocket下载流程
  Future<void> _handleWebSocketDownload({
    required String wsUrl,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    WebSocketChannel? wsChannel;
    int? downloadRecordId; // 保存下载记录ID

    try {
      print('🔗 连接WebSocket: $wsUrl');

      // 检查并获取下载控制器
      if (!Get.isRegistered<DownloadController>()) {
        Get.put(DownloadController(), permanent: true);
      }
      final downloadController = Get.find<DownloadController>();

      // 注意：startTime 和 endTime 已经是 ISO 格式（从 _convertTimeFormatToISOForWebSocket 转换来的）
      // 不需要再次转换，直接使用
      final startTimeISO = startTime;
      final endTimeISO = endTime;

      // 在WebSocket连接开始时，立即创建下载记录（状态为等待中）
      // 这样用户可以在下载页面立即看到下载项
      downloadRecordId = await _createWaitingDownloadRecord(
        downloadController: downloadController,
        startTime: startTimeISO,
        endTime: endTimeISO,
        duration: duration,
        picUrl: picUrl,
      );

      // 构建带查询参数的WebSocket URL（与device_detail_controller保持一致）
      final uri = Uri.parse(wsUrl);
      final queryParameters = {
        'serial': _deviceId,
        'code': _channelId,
        'starttime': startTime,
        'endtime': endTime,
        'timeout': '15',
      };

      final wsUri = uri.replace(queryParameters: queryParameters);
      print('🔗 完整WebSocket URL: $wsUri');

      // 连接WebSocket（参数通过URL查询参数传递）
      wsChannel = WebSocketChannel.connect(wsUri);

      // 监听WebSocket响应
      await for (final message in wsChannel.stream) {
        try {
          final response = jsonDecode(message.toString());
          print('📥 WebSocket响应: $response');

          final status = response['status'] as String?;
          final messageText = response['message'] as String?;
          final data = response['data'] as Map<String, dynamic>?;

          if (status == 'success') {
            print('✅ 下载任务已启动');
            // 更新状态为"正在连接服务器资源"
            if (downloadRecordId != null) {
              await _updateWebSocketProgress(
                downloadController: downloadController,
                recordId: downloadRecordId,
                progress: 0,
              );
            }
          } else if (status == 'download') {
            // 实时更新WebSocket进度
            final progress = data?['progress'] as int? ?? 0;
            print('⏳ 流媒体处理中... 进度: $progress%');
            if (downloadRecordId != null) {
              await _updateWebSocketProgress(
                downloadController: downloadController,
                recordId: downloadRecordId,
                progress: progress,
              );
            }
          } else if (status == 'finish') {
            print('🎯 流媒体处理完成，可以下载');

            final downloadUrl = data?['url'] as String?;

            if (downloadUrl != null && downloadUrl.isNotEmpty) {
              print('🔗 获取到下载链接: $downloadUrl');

              // 关闭WebSocket连接
              wsChannel.sink.close();

              // 更新下载记录并开始下载
              if (downloadRecordId != null) {
                unawaited(
                  _updateAndStartDownload(
                    downloadController: downloadController,
                    recordId: downloadRecordId,
                    downloadUrl: downloadUrl,
                    startTime: startTimeISO,
                    endTime: endTimeISO,
                    duration: duration,
                    picUrl: picUrl,
                  ),
                );
              } else {
                // 如果记录ID不存在，使用原来的方式创建新记录
                unawaited(
                  _startDirectDownload(
                    downloadUrl: downloadUrl,
                    startTime: startTime,
                    endTime: endTime,
                    duration: duration,
                    picUrl: picUrl,
                  ),
                );
              }

              return; // WebSocket流程完成，下载在后台进行
            } else {
              throw Exception('下载链接为空');
            }
          } else if (status == 'error') {
            final errorMsg = messageText ?? '下载处理失败';
            print('❌ WebSocket错误: $errorMsg');
            // 更新下载记录状态为失败
            if (downloadRecordId != null) {
              await _updateDownloadRecordStatus(
                downloadController: downloadController,
                recordId: downloadRecordId,
                status: DownloadStatus.failed,
                errorMessage: errorMsg,
              );
            }
            BotToast.showText(text: '录像处理失败: $errorMsg');
            throw Exception(errorMsg);
          }
        } catch (e) {
          print('❌ WebSocket消息解析失败: $e');
          // 更新下载记录状态为失败
          if (downloadRecordId != null) {
            await _updateDownloadRecordStatus(
              downloadController: downloadController,
              recordId: downloadRecordId,
              status: DownloadStatus.failed,
              errorMessage: 'WebSocket通信异常',
            );
          }
          BotToast.showText(text: '网络环境不佳，请稍后尝试');
          throw Exception('WebSocket通信异常');
        }
      }
    } catch (e) {
      print('❌ WebSocket下载流程失败: $e');
      // 更新下载记录状态为失败
      if (downloadRecordId != null) {
        if (Get.isRegistered<DownloadController>()) {
          final downloadController = Get.find<DownloadController>();
          await _updateDownloadRecordStatus(
            downloadController: downloadController,
            recordId: downloadRecordId,
            status: DownloadStatus.failed,
            errorMessage: 'WebSocket连接失败',
          );
        }
      }
      BotToast.showText(text: '网络环境不佳，请稍后尝试');
    } finally {
      // 确保WebSocket连接被关闭
      wsChannel?.sink.close();
    }
  }

  /// 开始直接下载
  Future<void> _startDirectDownload({
    required String downloadUrl,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      print('🎯 开始直接下载...');

      // 检查并获取下载控制器
      if (!Get.isRegistered<DownloadController>()) {
        print('❌ DownloadController 未注册，尝试重新注册');
        Get.put(DownloadController(), permanent: true);
      }

      final downloadController = Get.find<DownloadController>();
      print('✅ 成功获取下载控制器');

      // 转换时间格式（从YYYYMMDDHHmmss到ISO格式）
      final startTimeISO = _convertTimeFormatToISO(startTime);
      final endTimeISO = _convertTimeFormatToISO(endTime);

      print('🎬 转换后的ISO时间格式:');
      print('  开始时间: $startTimeISO');
      print('  结束时间: $endTimeISO');

      // 检查是否已存在相同的下载记录
      final existingRecords =
          downloadController.downloadRecords
              .where(
                (record) =>
                    record.videoUrl == downloadUrl &&
                    record.startTime == startTimeISO &&
                    record.endTime == endTimeISO,
              )
              .toList();

      if (existingRecords.isNotEmpty) {
        final existingRecord = existingRecords.first;
        if (existingRecord.status == DownloadStatus.waiting ||
            existingRecord.status == DownloadStatus.downloading) {
          BotToast.showText(text: '该视频正在下载中，请稍候');
          return;
        } else if (existingRecord.status == DownloadStatus.completed) {
          BotToast.showText(text: '下载完成，请前往我的下载进行查看');
          return;
        } else if (existingRecord.status == DownloadStatus.failed ||
            existingRecord.status == DownloadStatus.paused) {
          if (existingRecord.status == DownloadStatus.failed) {
            BotToast.showText(text: '检测到失败的下载，正在重新开始...');
          } else {
            BotToast.showText(text: '检测到暂停的下载，正在重新开始...');
          }
        }
      }

      // 开始下载 - 使用MP4下载方法（会在下载页面直接追加记录）
      print('🚀 调用startMp4Download方法...');
      await downloadController.startMp4Download(
        downloadUrl: downloadUrl,
        deviceName: _deviceName,
        deviceId: _deviceId,
        channelId: _channelId,
        channelName: _channelName,
        startTime: startTimeISO,
        endTime: endTimeISO,
        duration: duration,
        picUrl: picUrl.isNotEmpty ? picUrl : '',
      );

      print('✅ 录像下载已启动，记录已添加到下载页面');

      // 强制更新UI
      update();
    } catch (e) {
      print('❌ 直接下载失败: $e');
      BotToast.showText(text: '下载服务未初始化，请稍后重试');
    }
  }

  /// 创建等待中的下载记录（在WebSocket连接开始时调用）
  Future<int?> _createWaitingDownloadRecord({
    required DownloadController downloadController,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      // 检查是否已存在相同的下载记录（基于设备ID、通道ID和时间）
      // 注意：这里不检查videoUrl，因为WebSocket流程中videoUrl是空的
      final existingRecords =
          downloadController.downloadRecords
              .where(
                (record) =>
                    record.startTime == startTime &&
                    record.endTime == endTime &&
                    record.deviceId == _deviceId &&
                    record.channelId == _channelId &&
                    (record.status == DownloadStatus.waiting ||
                        record.status == DownloadStatus.downloading ||
                        (record.videoUrl.isEmpty && record.status == DownloadStatus.waiting)),
              )
              .toList();

      if (existingRecords.isNotEmpty) {
        print('⚠️ 已存在相同的等待中下载记录，使用现有记录 ID: ${existingRecords.first.id}');
        return existingRecords.first.id;
      }

      // 获取用户ID（通过DownloadController的内部方法）
      final userId = await _getCurrentUserIdForDownload(downloadController);

      // 创建下载记录（videoUrl暂时为空，等待WebSocket返回）
      final record = DownloadRecord(
        userId: userId,
        deviceId: _deviceId,
        deviceName: _deviceName,
        channelId: _channelId,
        channelName: _channelName,
        videoUrl: '', // 暂时为空，等待WebSocket返回
        localPath: '',
        fileName: '',
        startTime: startTime,
        endTime: endTime,
        duration: duration,
        fileSize: '0B',
        downloadedSize: '0B',
        progress: 0.0,
        speed: '0B/s',
        status: DownloadStatus.waiting,
        createdAt: DateTime.now(),
        picUrl: picUrl,
      );

      // 保存到数据库
      final databaseService = DownloadDatabaseService();
      final id = await databaseService.insertDownloadRecord(record);
      final savedRecord = record.copyWith(id: id);

      // 添加到列表
      downloadController.downloadRecords.insert(0, savedRecord);

      print('📝 创建等待中下载记录: ${savedRecord.deviceName} - ID: $id');

      // 强制更新UI
      downloadController.update();

      return id;
    } catch (e) {
      print('❌ 创建等待中下载记录失败: $e');
      return null;
    }
  }

  /// 获取当前用户ID（用于下载）
  Future<int> _getCurrentUserIdForDownload(
    DownloadController downloadController,
  ) async {
    try {
      final userService = Get.find<UserService>();
      final userId = userService.userId;
      if (userId != null) {
        return userId;
      }
      print('⚠️ 用户未登录，使用默认用户ID: 0');
      return 0;
    } catch (e) {
      print('❌ 获取用户ID失败: $e，使用默认用户ID: 0');
      return 0;
    }
  }

  /// 更新下载记录并开始下载
  Future<void> _updateAndStartDownload({
    required DownloadController downloadController,
    required int recordId,
    required String downloadUrl,
    required String startTime,
    required String endTime,
    required String duration,
    required String picUrl,
  }) async {
    try {
      // 查找记录
      final record = downloadController.downloadRecords.firstWhere(
        (r) => r.id == recordId,
      );

      // 更新记录的videoUrl和状态，重置进度信息
      final updatedRecord = record.copyWith(
        videoUrl: downloadUrl,
        downloadedSize: '0B',
        progress: 0.0,
        speed: '0B/s',
        status: DownloadStatus.waiting,
      );

      // 更新数据库
      final databaseService = DownloadDatabaseService();
      await databaseService.updateDownloadRecord(updatedRecord);

      // 更新本地列表
      final index = downloadController.downloadRecords.indexWhere(
        (r) => r.id == recordId,
      );
      if (index >= 0) {
        downloadController.downloadRecords[index] = updatedRecord;
      }

      // 强制更新UI
      downloadController.downloadRecords.refresh();
      downloadController.update();

      print('✅ 下载记录已更新，准备开始下载: ${updatedRecord.deviceName}');

      // 直接调用下载服务，使用现有记录ID，避免创建新记录
      // 通过反射或直接访问私有方法，或者使用公共方法
      // 这里我们使用 startMp4DownloadWithRecordId 方法（如果存在）
      // 或者直接调用下载服务
      await downloadController.startMp4DownloadWithRecordId(
        recordId: recordId,
        downloadUrl: downloadUrl,
      );

      print('✅ 下载已启动: ${updatedRecord.deviceName}');
    } catch (e) {
      print('❌ 更新并开始下载失败: $e');
      // 如果更新失败，尝试使用原来的方式创建新记录
      await _startDirectDownload(
        downloadUrl: downloadUrl,
        startTime: startTime,
        endTime: endTime,
        duration: duration,
        picUrl: picUrl,
      );
    }
  }

  /// 更新WebSocket进度
  Future<void> _updateWebSocketProgress({
    required DownloadController downloadController,
    required int recordId,
    required int progress,
  }) async {
    try {
      final record = downloadController.downloadRecords.firstWhere(
        (r) => r.id == recordId,
        orElse: () => throw Exception('记录不存在'),
      );

      // 更新下载记录的进度信息，使用downloadedSize字段显示进度
      final updatedRecord = record.copyWith(
        downloadedSize: '正在连接服务器资源 $progress%',
        progress: progress / 100.0, // 转换为0-1之间的进度值
        status: DownloadStatus.waiting, // 保持等待状态，直到获取到下载链接
      );

      // 更新数据库
      final databaseService = DownloadDatabaseService();
      await databaseService.updateDownloadRecord(updatedRecord);

      // 更新本地列表
      final index = downloadController.downloadRecords.indexWhere(
        (r) => r.id == recordId,
      );
      if (index >= 0) {
        downloadController.downloadRecords[index] = updatedRecord;
      }

      // 强制更新UI
      downloadController.downloadRecords.refresh();
      downloadController.update();

      print('✅ WebSocket进度已更新: ${updatedRecord.deviceName} - $progress%');
    } catch (e) {
      print('❌ 更新WebSocket进度失败: $e');
    }
  }

  /// 更新下载记录状态
  Future<void> _updateDownloadRecordStatus({
    required DownloadController downloadController,
    required int recordId,
    required DownloadStatus status,
    String? errorMessage,
  }) async {
    try {
      final record = downloadController.downloadRecords.firstWhere(
        (r) => r.id == recordId,
        orElse: () => throw Exception('记录不存在'),
      );

      final updatedRecord = record.copyWith(
        status: status,
        errorMessage: errorMessage,
      );

      // 更新数据库
      final databaseService = DownloadDatabaseService();
      await databaseService.updateDownloadRecord(updatedRecord);

      // 更新本地列表
      final index = downloadController.downloadRecords.indexWhere(
        (r) => r.id == recordId,
      );
      if (index >= 0) {
        downloadController.downloadRecords[index] = updatedRecord;
      }

      // 强制更新UI
      downloadController.downloadRecords.refresh();
      downloadController.update();

      print('✅ 下载记录状态已更新: ${updatedRecord.deviceName} - $status');
    } catch (e) {
      print('❌ 更新下载记录状态失败: $e');
    }
  }

  /// 格式化日期时间为云端API格式 (YYYYMMDDHHmmss)
  String _formatDateTimeForCloudAPI(DateTime date) {
    return '${date.year}${date.month.toString().padLeft(2, '0')}${date.day.toString().padLeft(2, '0')}${date.hour.toString().padLeft(2, '0')}${date.minute.toString().padLeft(2, '0')}${date.second.toString().padLeft(2, '0')}';
  }

  /// 转换时间格式（从YYYYMMDDHHmmss到ISO格式）
  String _convertTimeFormatToISO(String timeStr) {
    try {
      if (timeStr.length >= 14) {
        // 格式：YYYYMMDDHHMMSS
        final year = timeStr.substring(0, 4);
        final month = timeStr.substring(4, 6);
        final day = timeStr.substring(6, 8);
        final hour = timeStr.substring(8, 10);
        final minute = timeStr.substring(10, 12);
        final second = timeStr.substring(12, 14);

        return '$year-$month-${day}T$hour:$minute:$second';
      } else {
        print('⚠️ 时间格式不正确: $timeStr');
        return timeStr;
      }
    } catch (e) {
      print('⚠️ 时间格式转换失败: $e');
      return timeStr;
    }
  }

  /// 转换时间格式为WebSocket需要的ISO格式（从YYYYMMDDHHmmss到YYYY-MM-DDTHH:mm:00）
  /// WebSocket需要秒数固定为00
  String _convertTimeFormatToISOForWebSocket(String timeStr) {
    try {
      if (timeStr.length >= 14) {
        // 格式：YYYYMMDDHHMMSS
        final year = timeStr.substring(0, 4);
        final month = timeStr.substring(4, 6);
        final day = timeStr.substring(6, 8);
        final hour = timeStr.substring(8, 10);
        final minute = timeStr.substring(10, 12);
        // 秒数固定为00（WebSocket要求）
        return '$year-$month-${day}T$hour:$minute:00';
      } else {
        print('⚠️ 时间格式不正确: $timeStr');
        return timeStr;
      }
    } catch (e) {
      print('⚠️ 时间格式转换失败: $e');
      return timeStr;
    }
  }

  /// 转换时间格式为 API 需要的格式（从YYYYMMDDHHmmss到YYYY-MM-DDTHH:mm:ss）
  String _convertTimeFormatToAPI(String timeStr) {
    try {
      if (timeStr.length >= 14) {
        // 格式：YYYYMMDDHHMMSS
        final year = timeStr.substring(0, 4);
        final month = timeStr.substring(4, 6);
        final day = timeStr.substring(6, 8);
        final hour = timeStr.substring(8, 10);
        final minute = timeStr.substring(10, 12);
        final second = timeStr.substring(12, 14);

        return '$year-$month-${day}T$hour:$minute:$second';
      } else {
        print('⚠️ 时间格式不正确: $timeStr');
        return timeStr;
      }
    } catch (e) {
      print('⚠️ 时间格式转换失败: $e');
      return timeStr;
    }
  }

  /// 下载时间范围内的录像
  Future<void> downloadTimeRange() async {
    try {
      print('🎬 开始下载时间范围内的录像');
      print('🎬 开始时间: ${startTime.value}');
      print('🎬 结束时间: ${endTime.value}');
      print('🎬 存储类型: ${storageType.value}');

      // 解析时间范围
      final startDateTime = DateTime.parse(startTime.value);
      final endDateTime = DateTime.parse(endTime.value);

      // 格式化时间为云端API需要的格式 (YYYYMMDDHHmmss)
      final startTimeStr = _formatDateTimeForCloudAPI(startDateTime);
      final endTimeStr = _formatDateTimeForCloudAPI(endDateTime);

      print('🎬 格式化后的时间:');
      print('  开始时间: $startTimeStr');
      print('  结束时间: $endTimeStr');

      if (storageType.value == 'cloud') {
        // 云端录像下载
        await _handleCloudVideoDownload(
          startTime: startTimeStr,
          endTime: endTimeStr,
          duration: _calculateDuration(startDateTime, endDateTime),
          picUrl: '',
        );
      } else {
        // 本地录像下载
        await _handleLocalVideoDownload(
          startTime: startTimeStr,
          endTime: endTimeStr,
          duration: _calculateDuration(startDateTime, endDateTime),
          picUrl: '',
        );
      }
    } catch (e) {
      print('❌ 下载时间范围录像失败: $e');
      BotToast.showText(text: '下载失败，请稍后重试');
      BotToast.closeAllLoading();
    }
  }

  /// 计算时长
  String _calculateDuration(DateTime start, DateTime end) {
    final duration = end.difference(start);
    final minutes = duration.inMinutes;
    final seconds = duration.inSeconds % 60;
    return "${minutes}'${seconds.toString().padLeft(2, '0')}\"";
  }

  /// 检查存储权限
  Future<void> _checkStoragePermission() async {
    try {
      print('🔐 检查存储权限...');

      // 这里可以添加权限检查逻辑
      // 如果权限不足，应该提示用户授权
      print('✅ 存储权限检查通过');
    } catch (e) {
      print('❌ 存储权限检查失败: $e');
      BotToast.showText(text: '存储权限不足，请检查应用权限设置');
      throw Exception('存储权限不足');
    }
  }

  /// 前往我的下载页面
  void goToMyDownloads() {
    // 这里可以跳转到下载管理页面
    Get.snackbar('提示', '跳转到我的下载页面', snackPosition: SnackPosition.BOTTOM);
  }
}
